#include <iostream>
#include "glog/logging.h"
#include "gtest/gtest.h"
#include "emock/emock.hpp"

using namespace std;

class EmockDemoTest : public testing::Test
{
protected:
    void SetUp() override
    {
        std::cout << "--Gtest_Ut SetUP--" << std::endl;
    }

    void TearDown() override
    {
        std::cout << "--Gtest_Ut TearDown--" << std::endl;
    }
};

// 待测函数
int foobar(int x) {
    return x;
}

TEST_F(EmockDemoTest, EmockDemoTest_01)
{
//    // 测试时，像下面这样就可以mock
//    EMOCK(foobar)
//    .stubs()
//    .with(any()) // 约束匹配任意输入
//    .will(returnValue(1)); // 调用时返回1
//
//    // 调用会返回1
//    ASSERT_EQ(foobar(0), 1);
}

// 待测成员函数
class Foo
{
public:
    void bar1(int) {};
    virtual void bar2(double) {};
    static int bar3() {return -1;};
};

// 指定调用的mock函数
void mock_bar1(Foo* obj, int) {
    // ...
}
void mock_bar2(Foo* obj, double) {
    // ...
}

TEST_F(EmockDemoTest, EmockDemoTest_02)
{
//    // 测试时，像下面这样就可以mock
//    EMOCK(&Foo::bar1)
//        .stubs()
//        .will(invoke(mock_bar1)); // 指定调用自定义的函数而不是指定返回值
//    EMOCK(&Foo::bar2) // 虚成员函数并不特别
//        .stubs()
//        .will(invoke(mock_bar2));
//    EMOCK(Foo::bar3) // 静态函数类似全局函数，不需要&
//        .stubs()
//        .will(returnValue(1));
}

// 待测重载函数
double foobar(double x) {
    return x;
}

TEST_F(EmockDemoTest, EmockDemoTest_03)
{
    // 测试时，像下面这样就可以mock
    // 重载函数，像下面这样就可以mock
//    EMOCK((int (*)(int))foobar)
//            .stubs()
//            .will(returnValue(1));
//    EMOCK(static_cast<double (*)(double)>(foobar))
//            .stubs()
//            .will(returnValue(1.0));
}

// 待测重载成员函数
class Foo1
{
public:
    void bar(int) {};
    void bar(double) {};
};

TEST_F(EmockDemoTest, EmockDemoTest_04)
{
    // 重载的成员函数，像下面这样就可以mock
//    EMOCK((void (Foo1::*)(int))&Foo1::bar)
//            .expects(once()); // 只会调用一次
//            EMOCK(static_cast<void (Foo1::*)(double)>(&Foo1::bar))
//            .expects(never()); // 不会被调用
}



